/*
 * @FileName: fsm.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-17 13:17:46
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-08-09 15:03:53
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "bsp.h"
#include "fsm.h"

/**
 * @description: 状态机配置
 * @param fsm 状态机对象
 * @param sta 状态跳转表地址
 * @param act 动作执行表地址
 * @param check 事件检查函数表地址
 * @return 无
 */
void fsm_config(fsm_t * fsm, uint16_t (*sta)[EVENT_NUM], sta_action_t (*act)[EVENT_NUM], sta_check_t * check)
{
    fsm->sta_tbl = sta;
    fsm->action = act;
    fsm->check = check;
}

/**
 * @description: 状态机运行处理
 * @param fsm 状态机对象
 * @return 无
 */
void fsm_handler(fsm_t * fsm)
{
    uint16_t sta_cur = fsm->sta_cur;     // 获取当前状态
    uint16_t ev = fsm->check[sta_cur](); // 获取发生的事件
    uint16_t sta_next = fsm->sta_tbl[sta_cur][ev]; // 获取事件对应要跳转的下一个状态

    // if (sta_cur == sta_next) {
    //     return;
    // }

    sta_action_t handle = fsm->action[sta_cur][ev]; // 获取跳转下个状态要做的动作

    if (handle != NULL) { 
        handle(); // 执行动作
    }

    fsm->sta_cur = sta_next; // 状态跳转
    fsm->time++;
}

/**
 * @description: 状态机计时复位
 * @param fsm 状态机对象
 * @return 无
 */
void fsm_time_reset(fsm_t * fsm) {
    fsm->time = 0;
}

/**
 * @description: 判断状态机是否超时
 * @param fsm 状态机对象
 * @return true or false
 */
bool fsm_is_timeout(fsm_t * fsm, uint32_t time_exp) {
    return (fsm->time > time_exp);
}



